package android.Graphics;

import android.GameLogic.GameLogic;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: akuryou
 * Date: 4/25/11
 * Time: 4:10 PM
 * To change this template use File | Settings | File Templates.
 */
public class GameRenderer implements Renderer
{
    //Width and height of screen, sent over in constructor.
    private float width;
    private float height;
    private int boardSize; // Defines the nxn matrix that forms the playing field.
    private int cellWidth;
    private int cellHeight;
    private final int LINE_WIDTH = 3;
    private int[][] symbols;
    private String header;
    private String winner;

    private boolean finished = false;

    private int playerID = 1;
    private int gameRound = 1;
    private int players;
    private int gameType;

    private int bX; // X element in the playing field array
    private int bY; // Y element in the playing field array

    private InitBoard board;
    private GameLogic logic;

    private InitStar star;
    private InitDiamond diamond;
    private InitTriangle triangle;

    private ArrayList<InitStar> stars           = new ArrayList<InitStar>();
    private ArrayList<InitDiamond> diamonds     = new ArrayList<InitDiamond>();
    private ArrayList<InitTriangle> triangles   = new ArrayList<InitTriangle>();

    public boolean playerWon = false;

    public GameRenderer( Context context, float width, float height, int boardSize, int players )
    {
        this.width = width;
        this.height = height;
        this.boardSize = boardSize;
        this.players = players;
        this.gameType = boardSize;
        board = new InitBoard( width, height, boardSize, players );
    }

    public boolean getPlayerWon() { return finished; }
    public String getWinner() {return winner; }
    public int getPlayerID() { return playerID; } // stops the players from clicking after a player has won!

    public void onSurfaceCreated( GL10 gl, EGLConfig eglConfig )
    {
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glOrthof(width, 0.0f, height, 0.0f, -1.0f, 1.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        board.initBoard();
        logic = new GameLogic();

        /**
         * changes the size of the gameboard when the amount of players are 3.
         */
        if( boardSize == 3 && players == 3 ) { boardSize = 2 * boardSize; }
        if(boardSize == 4 && players == 2) {boardSize += 3;}
        if(boardSize == 5 && players == 2) {boardSize += 3;}
        symbols = new int[boardSize][boardSize]; // Array for remembering the symbols to draw
        cellWidth = (int) width/boardSize;
        cellHeight = (int) (height)/boardSize;
    }

    public void onSurfaceChanged( GL10 gl, int w, int h )
    {
        gl.glViewport( 0, 0, w, h );
        gl.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
        gl.glMatrixMode( GL10.GL_PROJECTION );
        gl.glLoadIdentity();
        gl.glClear( GL10.GL_COLOR_BUFFER_BIT );
        gl.glOrthof( 0.0f, w, 0.0f, h, -1.0f, 1.0f );
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();

        width = w;
        height = h;
        cellWidth = (int) width/boardSize;
        cellHeight = (int) height/boardSize;
        board.initBoard();
    }

    public void onDrawFrame( GL10 gl )
    {
        gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();

        gl.glPushMatrix();
            gl.glColor4f( 0.75f, 0.20f, 0.64f, 1.0f );
            gl.glLineWidth( LINE_WIDTH );
            board.drawBoard( gl );
        gl.glPopMatrix();

        /**
         * Draws the symbols on the field.
         */

        drawSymbols( gl );
    }

    public String getHeader() { return header; }

    public void setHeader( String text ) { this.header = text; }

    public void drawSymbol( float x, float y )
    {
        bX = (int) ((x/width) * boardSize); // Calculates which x-element in the matrix is touched
        bY = (int) (((height-y)/height) * boardSize); // Calculates which y-element in the matrix is touched
        //while ( gameRound < bX*bY )
        switch ( playerID )
        {
            case 1:
                if( symbols[bX][bY] == 0 )
                {
                    symbols[bX][bY] = 1;
                    stars.add( new InitStar(bX, bY, cellWidth, cellHeight, LINE_WIDTH) );
                    if( logic.playerWon( symbols, bX, bY, playerID, gameType ) )
                    {
                        playerWon = true;
                        setHeader( "Player " + playerID + " is winrar!" );
                        winner = "player " +playerID;
                        finished = true;
                        playerID = 0;
                        break;
                    }
                    playerID = 2;
                    setHeader( "Player " + playerID + "'s turn." );
                    gameRound++;
                }
                break;

            case 2:
                if( symbols[bX][bY] == 0 )
                {
                    symbols[bX][bY] = 2;
                    diamonds.add( new InitDiamond(bX, bY, cellWidth, cellHeight, LINE_WIDTH) );
                    if( logic.playerWon( symbols, bX, bY, playerID, gameType ) )
                    {
                        playerWon = true;
                        setHeader( "Player " + playerID + " is winrar!" );
                        winner = "player " +playerID;
                        finished = true;
                        playerID = 0;
                        break;
                    }
                    if( players == 3 )
                    {
                        playerID = 3;
                        setHeader( "Player " + playerID + "'s turn." );
                        gameRound++;
                        break;
                    }
                    playerID = 1;
                    setHeader( "Player " + playerID + "'s turn." );
                    gameRound++;
                }
                break;

            case 3:
                if( symbols[bX][bY] == 0 )
                {
                    symbols[bX][bY] = 3;
                    triangles.add( new InitTriangle(bX, bY, cellWidth, cellHeight, LINE_WIDTH) );
                    if( logic.playerWon( symbols, bX, bY, playerID, gameType ) )
                    {
                        playerWon = true;
                        setHeader( "Player " + playerID + " is winrar!" );
                        winner = "player " +playerID;
                        finished = true;
                        playerID = 0;
                        break;
                    }
                    playerID = 1;
                    setHeader( "Player " + playerID + "'s turn." );
                    gameRound++;
                }
                break;
        }
    }

    public void drawSymbols( GL10 gl )
    {
        for( int i = 0; i < stars.size(); ++i )
        {
            gl.glColor4f( 1.0f, 1.0f, 0.0f, 0.0f );
            stars.get( i ).drawStar( gl );
        }
        for( int j = 0; j < diamonds.size(); ++j )
        {
            if( playerWon ) gl.glColor4f( 0.75f, 0.75f, 0.75f, 0.0f );
            gl.glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
            diamonds.get( j ).drawDiamond( gl );
        }
        for( int k = 0; k < triangles.size(); ++k )
        {
            if( playerWon ) gl.glColor4f( 0.75f, 0.75f, 0.75f, 0.0f );
            gl.glColor4f( 0.0f, 1.0f, 0.0f, 0.0f );
            triangles.get( k ).drawTriangle( gl );
        }
    }

    /**
     * Clears the arrays and resets the board.
     */

    public void restart()
    {
        if( playerWon || gameRound > bY*bX )
        {
            for( int i = 0; i < symbols.length; ++ i )
            {
                for( int j = 0; j < symbols[0].length; ++j )
                {
                    symbols[i][j] = 0;
                }
            }
        }

        for( int k = 0; k < stars.size(); ++k ) stars.remove(k);
        for( int l = 0; l < diamonds.size(); ++l ) diamonds.remove(l);
        for( int m = 0; m < triangles.size(); ++m ) triangles.remove(m);
    }
}